MYC-deficiency impairs the development of effector/memory T lymphocytes
Authors :Mathis Nozais1*, Marie Loosveld1,2*, Saran Pankaew1, Clémence Grosjean1, Noémie Gentil1, Julie Quessada1, Cyrille Mionnet1, Delphine Potier1@ & Dominique Payet-Bornet1@
*These authors contributed equally: Mathis Nozais, Marie Loosveld; @ Corresponding authors: Dr Delphine Potier and Dr Dominique Payet-Bornet
Link to article : (TO come)
This code is made to be running on Seurat 301v2 Docker. Data and explanation about this code are available at : https://github.com/mathisnozais/MycPten
Any questions on this analysis, please contact Mathis Nozais (nozais@ciml.univ-mrs.fr) or Delphine Potier (potier@ciml.univ-mrs.fr)
[1] “You are starting the analysis from count matrix obtain with CellRanger and Cite-seq-count”
Loading the first experiment
Looking to HTO distribution accross sample :
#HTO distribution
par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto1), main = "Sequenced HTO distribution", horiz=TRUE)

rowSums(hto1)
## Spleen-MP Spleen-M Spleen-ctrl Spleen-P Thymus-MP Thymus-M
## 688432 206663 265412 662165 196262 117402
## Thymus-ctrl Thymus-P
## 156856 562594
Demultiplexing HTO
Demultiplex cells based on HTO enrichment
Demultiplexing results
Cells classification
datatable(as.matrix(table(hashtag1@meta.data$MULTI_ID)),colnames = "Number of cells")
Violinplot (features)
VlnPlot(hashtag1,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

Violinplot (HTO counts)
VlnPlot(hashtag1,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

tSNEs based on HTO
# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag1, assay = "HTO"))))
# Calculate tSNE embeddings with a distance matrix
hashtag1 <- RunTSNE(hashtag1, distance.matrix = hto.dist.mtx, perplexity = 100)

HTO margin
Tsne<-data.frame(
tSNE_1 = hashtag1@reductions$tsne@cell.embeddings[,1],
tSNE_2= hashtag1@reductions$tsne@cell.embeddings[,2],
gene= hashtag1@meta.data$HTO_margin
)
HTO= hashtag1@meta.data$MULTI_ID
Max=max(hashtag1@meta.data$HTO_margin)
Min=min(hashtag1@meta.data$HTO_margin)
ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots
Visualize enrichment for selected HTOs with ridge plots
RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information
The analysis will be run on the sample 1.
During the sample loading, we filter cells that do not pass the following filters.
Here are the description of those parameters in the Seurat CreateSeuratObject function:
- min.genes: Include cells where at least 200 genes are detected
- min.cells: Include genes with detected expression in at least 3 cells
a <- length(colnames(hashtag1@assays$RNA@data))
print(paste("After those filters, the remaining cell number is", a), quote = FALSE)
## [1] After those filters, the remaining cell number is 4187
#add Exp1 cell identity
HTO_cr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-ctrl" ))
HTO_mr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-M" ))
HTO_mt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-M" ))
HTO_pr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-P" ))
HTO_pt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-P" ))
HTO_pmr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-MP" ))
HTO_pmt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-MP" ))
HTO_d1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Doublet" ))
HTO_n1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Negative" ))
HTO_thymus1 = c(HTO_ct1,HTO_mt1,HTO_pt1,HTO_pmt1)
HTO_spleen1 = c(HTO_cr1,HTO_mr1,HTO_pr1,HTO_pmr1)
HTO_identified1 = c(HTO_thymus1, HTO_spleen1)
# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset1 <- subset(x = hashtag1, cells = HTO_identified1)
VlnPlot(clean.subset1,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

a <- length(colnames(clean.subset1@assays$RNA@data))
print(paste("After removing doublets and negative cells, the remaining cell number is", a), quote = FALSE)
## [1] After removing doublets and negative cells, the remaining cell number is 3811
Mitochondrial percentage versus nFeatures
df<-data.frame(multi.id=Seurat1@misc$old_meta_data$MULTI_ID,percent.mito=Seurat1@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat1@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())
UMAP
ggplotly(DimPlot(Seurat1, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))
Loading the second experiment
par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto2), main = "sequenced HTO distribution", horiz=TRUE)

rowSums(hto2)
## Spleen-MP Spleen-M Spleen-ctrl Spleen-P Thymus-MP Thymus-M
## 3569690 1668124 929963 3251282 484276 749822
## Thymus-ctrl Thymus-P
## 310711 1203239
Demultiplexing results
Cells classification
datatable(as.matrix(table(hashtag2@meta.data$MULTI_ID)),colnames = "Number of cells")
Violinplot (features)
VlnPlot(hashtag2,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

Violin plots (HTO counts)
VlnPlot(hashtag2,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

tSNEs based on HTO
# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag2, assay = "HTO"))))
# Calculate tSNE embeddings with a distance matrix
hashtag2 <- RunTSNE(hashtag2, distance.matrix = hto.dist.mtx, perplexity = 100)
DimPlot(hashtag2, group.by = "MULTI_ID")

HTO margin
Tsne<-data.frame(
tSNE_1 = hashtag2@reductions$tsne@cell.embeddings[,1],
tSNE_2= hashtag2@reductions$tsne@cell.embeddings[,2],
gene= hashtag2@meta.data$HTO_margin
)
HTO= hashtag2@meta.data$MULTI_ID
Max=max(hashtag2@meta.data$HTO_margin)
Min=min(hashtag2@meta.data$HTO_margin)
ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots
Visualize enrichment for selected HTOs with ridge plots
RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information
The analysis will be run on the sample 2.
During the sample loading, we filter cells that do not pass the following filters.
Used parameters in the Seurat CreateSeuratObject function: * min.genes: 3 . Include cells where at least 3 genes are detected * min.cells: 200 . Include genes with detected expression in at least 200 cells
a <-length(colnames(hashtag2@assays$RNA@data))
print(paste("After those filters, the remaining cell number is", a), quote = FALSE)
## [1] After those filters, the remaining cell number is 12990
#add Exp2 cell identity
HTO_cr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-ctrl" ))
HTO_mr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-M" ))
HTO_mt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-M" ))
HTO_pr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-P" ))
HTO_pt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-P" ))
HTO_pmr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-MP" ))
HTO_pmt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-MP" ))
HTO_d2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Doublet" ))
HTO_n2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Negative" ))
HTO_thymus2 = c(HTO_ct2,HTO_mt2,HTO_pt2,HTO_pmt2)
HTO_spleen2 = c(HTO_cr2,HTO_mr2,HTO_pr2,HTO_pmr2)
HTO_identified2 = c(HTO_thymus2, HTO_spleen2)
# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset2 <- subset(x = hashtag2, cells = HTO_identified2)
VlnPlot(clean.subset2,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE, group.by = "MULTI_ID")

a <-length(colnames(clean.subset2@assays$RNA@data))
print(paste("After removing doublets and negative cells, the remaining cell number is", a), quote = FALSE)
## [1] After removing doublets and negative cells, the remaining cell number is 10309
Adding ADT
# Load in the UMI matrix
umi <- GetAssayData(object = clean.subset2, slot = "counts")
# Load in the ADT count matrix
raw.adt <- Read10X(PATH_ADT_DATA2, gene.column = 1)
adt <- raw.adt[c(1:6),]
rownames(adt) <- c("CD4","CD5","CD8","CD25","CD44","CD69")
#create an empty matrix containing NAs
Cell.list <- colnames(GetAssayData(object = clean.subset2[["RNA"]], slot = "data" ) )
ADT.list <- c(unique(rownames(adt)))
mat.adt <- matrix(nrow = length(ADT.list), ncol = length(Cell.list))
rownames(mat.adt) = ADT.list
colnames(mat.adt) = Cell.list
# Get cell barcodes detected by both RNA and ADT
joint_bcs <- intersect(colnames(umi),colnames(adt))
adt <- as.matrix(adt[,joint_bcs])
# Fill the empty matrix with values when existing
mat.adt[,joint_bcs]<-adt[,joint_bcs]
# Add ADT data as a new assay independent from RNA
clean.subset2[["ADT"]] <- CreateAssayObject(counts = mat.adt[,colnames(clean.subset2)])
# Normalize ADT data, here we use centered log-ratio (CLR) transformation
clean.subset2 <- NormalizeData(clean.subset2, assay = "ADT", normalization.method = "CLR")
#Scale
clean.subset2 <- ScaleData(clean.subset2, assay = "ADT")
ADT list :
print (rownames(adt))
[1] “CD4” “CD5” “CD8” “CD25” “CD44” “CD69”
Mitochondrial percentage versus nFeatures
df<-data.frame(multi.id=Seurat2@misc$old_meta_data$MULTI_ID,percent.mito=Seurat2@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat2@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())
UMAP:
ggplotly(DimPlot(Seurat2, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))
Analysis part
UMAP and clustering parameter
T-cell selection
According to T-cell markers we will exclude Cd3d low clusters: 13 (Bcells), 11, 14, 17 (monocytes/macrophages). According to T-cell markers we will exclude Cd3d/Cd3e low clusters: 11 (Bcells), 13, 17, 18, 19 (monocytes/macrophages), 16, 14 (ILC/NK).
re clustering

T-cell umaps
clustering

END OF PREPROCESSING
We obtain the final object with clustering to start the analysis
Session Info
sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
##
## Matrix products: default
## BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.18.so
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=C
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] knitr_1.23 RColorBrewer_1.1-2 magrittr_1.5
## [4] dplyr_0.8.1 DT_0.6.2 gridExtra_2.3
## [7] kableExtra_1.1.0 plotly_4.9.0 ggplot2_3.1.1
## [10] Seurat_3.0.1
##
## loaded via a namespace (and not attached):
## [1] nlme_3.1-140 tsne_0.1-3 bitops_1.0-6
## [4] webshot_0.5.1 httr_1.4.0 sctransform_0.2.0
## [7] tools_3.5.3 R6_2.4.0 irlba_2.3.3
## [10] KernSmooth_2.23-15 lazyeval_0.2.2 colorspace_1.4-1
## [13] npsurv_0.4-0 withr_2.1.2 tidyselect_0.2.5
## [16] compiler_3.5.3 rvest_0.3.4 xml2_1.2.0
## [19] labeling_0.3 caTools_1.17.1.2 scales_1.0.0
## [22] lmtest_0.9-37 readr_1.3.1 ggridges_0.5.1
## [25] pbapply_1.4-0 stringr_1.4.0 digest_0.6.19
## [28] rmarkdown_1.12 R.utils_2.8.0 base64enc_0.1-3
## [31] pkgconfig_2.0.2 htmltools_0.3.6 bibtex_0.4.2
## [34] highr_0.8 htmlwidgets_1.3 rlang_0.3.4
## [37] rstudioapi_0.10 shiny_1.3.2 zoo_1.8-5
## [40] jsonlite_1.6 crosstalk_1.0.0 ica_1.0-2
## [43] gtools_3.8.1 R.oo_1.22.0 Matrix_1.2-17
## [46] Rcpp_1.0.1 munsell_0.5.0 ape_5.3
## [49] reticulate_1.12 R.methodsS3_1.7.1 stringi_1.4.3
## [52] yaml_2.2.0 gbRd_0.4-11 MASS_7.3-51.4
## [55] gplots_3.0.1.1 Rtsne_0.15 plyr_1.8.4
## [58] grid_3.5.3 promises_1.0.1 parallel_3.5.3
## [61] gdata_2.18.0 listenv_0.7.0 ggrepel_0.8.1
## [64] crayon_1.3.4 lattice_0.20-38 cowplot_0.9.4
## [67] splines_3.5.3 hms_0.4.2 SDMTools_1.1-221.1
## [70] pillar_1.4.0 igraph_1.2.4.1 future.apply_1.2.0
## [73] reshape2_1.4.3 codetools_0.2-16 glue_1.3.1
## [76] evaluate_0.13 lsei_1.2-0 metap_1.1
## [79] data.table_1.12.2 httpuv_1.5.1 png_0.1-7
## [82] Rdpack_0.11-0 gtable_0.3.0 RANN_2.6.1
## [85] purrr_0.3.2 tidyr_0.8.3 future_1.13.0
## [88] assertthat_0.2.1 xfun_0.7 mime_0.6
## [91] rsvd_1.0.0 xtable_1.8-4 later_0.8.0
## [94] survival_2.44-1.1 viridisLite_0.3.0 tibble_2.1.1
## [97] cluster_2.0.9 globals_0.12.4 fitdistrplus_1.0-14
## [100] ROCR_1.0-7
LS0tCnRpdGxlOiAiUmVwb3J0IEV4cGVyaW1lbnRfUHJlcHJvY2Vzc2luZyIKYXV0aG9yOiAiRGVscGhpbmUgUG90aWVyIC8gTWF0aGlzIE5vemFpcyAvIFNhcmFuIFBhbmthZXciCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQoKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTgwMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQo8L3N0eWxlPgoKYGBge3IgZ2xvYmFsLW9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbGlnbiA9ICdjZW50ZXInKQpgYGAKIyBNWUMtZGVmaWNpZW5jeSBpbXBhaXJzIHRoZSBkZXZlbG9wbWVudCBvZiBlZmZlY3Rvci9tZW1vcnkgVCBseW1waG9jeXRlcwoKQXV0aG9ycyA6TWF0aGlzIE5vemFpczFcKiwgTWFyaWUgTG9vc3ZlbGQxLDJcKiwgU2FyYW4gUGFua2FldzEsIENsw6ltZW5jZSBHcm9zamVhbjEsIE5vw6ltaWUgR2VudGlsMSwgSnVsaWUgUXVlc3NhZGExLCBDeXJpbGxlIE1pb25uZXQxLCBEZWxwaGluZSBQb3RpZXIxQCAmIERvbWluaXF1ZSBQYXlldC1Cb3JuZXQxQAoKKlRoZXNlIGF1dGhvcnMgY29udHJpYnV0ZWQgZXF1YWxseTogTWF0aGlzIE5vemFpcywgTWFyaWUgTG9vc3ZlbGQ7IEAgQ29ycmVzcG9uZGluZyBhdXRob3JzOiBEciBEZWxwaGluZSBQb3RpZXIgYW5kIERyIERvbWluaXF1ZSBQYXlldC1Cb3JuZXQKCkxpbmsgdG8gYXJ0aWNsZSA6IChUTyBjb21lKQoKVGhpcyBjb2RlIGlzIG1hZGUgdG8gYmUgcnVubmluZyBvbiBTZXVyYXQgMzAxdjIgRG9ja2VyLiBEYXRhIGFuZCBleHBsYW5hdGlvbiBhYm91dCB0aGlzIGNvZGUgYXJlIGF2YWlsYWJsZSBhdCA6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYXRoaXNub3phaXMvTXljUHRlbgoKQW55IHF1ZXN0aW9ucyBvbiB0aGlzIGFuYWx5c2lzLCBwbGVhc2UgY29udGFjdCBNYXRoaXMgTm96YWlzIChub3phaXNAY2ltbC51bml2LW1ycy5mcikgb3IgRGVscGhpbmUgUG90aWVyIChwb3RpZXJAY2ltbC51bml2LW1ycy5mcikKCgpgYGB7ciBlbnZfbG9hZGluZywgaW5jbHVkZT1GQUxTRX0KIyBMb2FkIHBhY2thZ2VzLCBkYXRhIGFuZCBmdW5jdGlvbnMKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoRFQpCgojIExvYWQgdGhlIFIgc2NyaXB0cyBjb250YWluaW5nIHRoZSBmdW5jdGlvbnMgdXNlZCBpbiB0aGUgYW5hbHlzaXMKc291cmNlKHBhc3RlMChXT1JLSU5HX0RJUiwiLzAyX1NldXJhdF9hbmFseXNpcy8wMV9TY3JpcHQvV29ya2Zsb3dfZnVuY3Rpb24uUiIpKQoKIyAgUGF0aCB0byB0aGUgZm9sZGVyIHRoYXQgd2lsbCBjb250YWluIG91dHB1dCBvYmplY3RzCk9VVFBVVF9QQVRIIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDJfT3V0cHV0LyIpKQoKIyBTZXQgdGhlIHJhbmRvbSBudW1iZXIgc2VlZApzZXQuc2VlZCgxMjM0KQojIFJlc29sdXRpb24gcGFyYW1ldGVyIGZvciBTZXVyYXQgY2x1c3RlcmluZwpSRVNPTFVUSU9OIDwtIDEKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSxyZXN1bHRzPSdhc2lzJ30KU0FNUExFMSA8LSAicmVwbGljYXRlMSIKU0FNUExFMiA8LSAicmVwbGljYXRlMiIKCmlmKCghIGZpbGUuZXhpc3RzKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdF9jbGVhbi1zdWJzZXRfdG9tZXJnZV8iLCBTQU1QTEUxLCAiLlJvYmoiKSkpIHwgKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTIsICIuUm9iaiIpKSkpewpwcmludCgiWW91IGFyZSBzdGFydGluZyB0aGUgYW5hbHlzaXMgZnJvbSBjb3VudCBtYXRyaXggb2J0YWluIHdpdGggQ2VsbFJhbmdlciBhbmQgQ2l0ZS1zZXEtY291bnQiKQpwYXJ0MSA8LSBUUlVFICNleHBlcmltZW50IG9uZSBieSBvbmUKcGFydDIgPC0gVFJVRSAjbWVyZ2luZyAyIG9iamVjdAp9ZWxzZSBpZiggZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsIi5Sb2JqIikpKXsKcHJpbnQoIllvdSBhbHJlYWR5IGhhdmUgdGhlIGZpbmFsIG9iamVjdCBvZiBwcmVwcm9jZXNzaW5nLCB5b3UgY2FuIG5vdyBsYXVjaCB0aGUgRXhwZXJpbWVudF9hbmFseXNpcyBzY3JpcHQiKQpwYXJ0MSA8LSBGQUxTRQpwYXJ0MiA8LSBGQUxTRQp9ZWxzZXsgCnByaW50ICgiWW91IGFyZSBzdGFydGluZyBhbmFseXNpcyBmcm9tIG91ciB0d28gcmVwbGljYXRlIFJvYmogaW4gb3JkZXIgdG8gZG8gdGhlIGludGVncmF0aW9uIikKcGFydDEgPC0gRkFMU0UKcGFydDIgPC0gVFJVRQp9CmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyBMb2FkaW5nIHRoZSBmaXJzdCBleHBlcmltZW50CmBgYAoKCmBgYHtyIHBhdGgxX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApfQojIExvYWQgcGF0aCBmb3IgZmlsZXMKUEFUSF9NT1VTRV9EQVRBMSA8LSAocGFzdGUwKFdPUktJTkdfRElSLCIvMDJfU2V1cmF0X2FuYWx5c2lzLzAzX0RhdGEvUmVwbGljYXRlMS9tUk5BLyIpKQpQUk9KRUNUX05BTUUxIDwtIHBhc3RlKCIxMFhfIiwgU0FNUExFMSwgc2VwID0gIiIpClBBVEhfSFRPX0RBVEExIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDNfRGF0YS9SZXBsaWNhdGUxL0hUTy8iKSkKYGBgCgpgYGB7ciBTYW1wbGUxX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgQ3JlYXRlIFNldXJhdCBvYmplY3QgYW5kIGFwcGx5IGZpbHRlcmluZyAgIAojIFJlYWQgMTBYIGRhdGEKbW91c2VfZGF0YTEgPC0gUmVhZDEwWChkYXRhLmRpciA9IFBBVEhfTU9VU0VfREFUQTEpCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20xIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMSwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTEiKQpgYGAKCmBgYHtyIEhUTzFfbG9hZGluZywgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBMb2FkIGluIHRoZSBVTUkgbWF0cml4CnVtaV9zcGFyc2UxIDwtIEdldEFzc2F5RGF0YShvYmplY3QgPSBOb3RfcHJvY2Vzc2VkX1NldXJhdF9tMSwgc2xvdCA9ICJjb3VudHMiKQoKIyBMb2FkIGluIHRoZSBIVE8gY291bnQgbWF0cml4CnJhdy5odG8xIDwtIFJlYWQxMFgoUEFUSF9IVE9fREFUQTEsIGdlbmUuY29sdW1uID0gMSkKaHRvMSA8LSByYXcuaHRvMVtjKDE6OCksXQoKcm93bmFtZXMoaHRvMSkgPC0gYygiU3BsZWVuLU1QIiwiU3BsZWVuLU0iLCJTcGxlZW4tY3RybCIsIlNwbGVlbi1QIiwiVGh5bXVzLU1QIiwiVGh5bXVzLU0iLCJUaHltdXMtY3RybCIsIlRoeW11cy1QIikKCiMgU2VsZWN0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEhUTwojIEluIHRoZSBleGFtcGxlIGRhdGFzZXRzIHdlIGhhdmUgYWxyZWFkeSBmaWx0ZXJlZCB0aGUgY2VsbHMgZm9yIHlvdSwgYnV0IHBlcmZvcm0gdGhpcyBzdGVwIGZvciBjbGFyaXR5Lgpqb2ludF9iY3MxIDwtIGludGVyc2VjdChjb2xuYW1lcyh1bWlfc3BhcnNlMSksY29sbmFtZXMoaHRvMSkpCgojIFN1YnNldCBSTkEgYW5kIEhUTyBjb3VudHMgYnkgam9pbnQgY2VsbCBiYXJjb2Rlc3VtaV9zcGFyc2UgPC0gcGJtY191bWlfc3BhcnNlWyxqb2ludF9iY3NdCmh0bzEgPC0gYXMubWF0cml4KGh0bzFbLGpvaW50X2JjczFdKQoKIyBDb25maXJtIHRoYXQgdGhlIEhUTyBoYXZlIHRoZSBjb3JyZWN0IG5hbWVzCnByaW50IChyb3duYW1lcyhodG8xKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9Ckxvb2tpbmcgdG8gSFRPIGRpc3RyaWJ1dGlvbiBhY2Nyb3NzIHNhbXBsZSA6CmBgYAoKYGBge3IgSFRPIGRpc3RyaWJ1dGlvbixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiNIVE8gZGlzdHJpYnV0aW9uCnBhcihtZnJvdz1jKDEsMSkpCnBhcihsYXM9MikKcGFyKG1hcj1jKDUsMTUsMywzKSkKYmFycGxvdChyb3dTdW1zKGh0bzEpLCBtYWluID0gIlNlcXVlbmNlZCBIVE8gZGlzdHJpYnV0aW9uIiwgaG9yaXo9VFJVRSkKcm93U3VtcyhodG8xKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIyMgU2V0dXAgc2V1cmF0IG9iamVjdCBhbmQgYWRkIGluIHRoZSBodG8gZGF0YQojIFNldHVwIFNldXJhdCBvYmplY3QKaGFzaHRhZzEgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHVtaV9zcGFyc2UxWyxqb2ludF9iY3MxXSwgYXNzYXkgPSAiUk5BIiwgcHJvamVjdCA9ICJyZXBsaWNhdGUxIikKCiMgTm9ybWFsaXplIFJOQSBkYXRhIHdpdGggbG9nIG5vcm1hbGl6YXRpb24KaGFzaHRhZzEgPC0gTm9ybWFsaXplRGF0YShoYXNodGFnMSxkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCiMgRmluZCBhbmQgc2NhbGUgdmFyaWFibGUgZ2VuZXMKaGFzaHRhZzEgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoaGFzaHRhZzEsIHBhcnQxLnBsb3QgPSBGLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKaGFzaHRhZzEgPC0gU2NhbGVEYXRhKGhhc2h0YWcxLGdlbmVzLnVzZSA9IGhhc2h0YWcxQHZhci5mZWF0dXJlcyxkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMjIyBBZGRpbmcgSFRPIGRhdGEgYXMgYW4gaW5kZXBlbmRlbnQgYXNzYXkKCiMgQWRkIEhUTyBkYXRhIGFzIGEgbmV3IGFzc2F5IGluZGVwZW5kZW50IGZyb20gUk5BCmhhc2h0YWcxW1siSFRPIl1dIDwtIENyZWF0ZUFzc2F5T2JqZWN0KGNvdW50cyA9IGh0bzEpCmhhc2h0YWcxIDwtIFNldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iLHNsb3QgPSAiY291bnRzIixuZXcuZGF0YSA9IGh0bzEpCiMgTm9ybWFsaXplIEhUTyBkYXRhLCBoZXJlIHdlIHVzZSBjZW50ZXJlZCBsb2ctcmF0aW8gKENMUikgdHJhbnNmb3JtYXRpb24KaGFzaHRhZzEgPC0gTm9ybWFsaXplRGF0YShoYXNodGFnMSwgYXNzYXkgPSAiSFRPIixub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJDTFIiLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIERlbXVsdGlwbGV4aW5nIEhUTwpEZW11bHRpcGxleCBjZWxscyBiYXNlZCBvbiBIVE8gZW5yaWNobWVudApgYGAKCmBgYHtyIERlbXVsdGlwbGV4aW5nLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQoKI1J1biBIVE9kZW11eCBqdXN0IHRvIGdldCB0aGUgSFRPbWF4X0lEIGZpZWQKaGFzaHRhZzEgPC0gSFRPRGVtdXgoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIHBvc2l0aXZlLnF1YW50aWxlID0gMC45OSwgdmVyYm9zZSA9IEZBTFNFKQojSGVyZSB3ZSB1c2UgdGhlIFNldXJhdCBmdW5jdGlvbiBNVUxUSXNlcURlbXV4KCkgdG8gYXNzaWduIHNpbmdsZSBjZWxscyBiYWNrIHRvIHRoZWlyIHNhbXBsZSBvcmlnaW5zLgpoYXNodGFnMSA8LSBNVUxUSXNlcURlbXV4KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLGF1dG9UaHJlc2ggPSBUUlVFLCBtYXhpdGVyID0gMTAscXJhbmdlID0gc2VxKGZyb20gPSAwLjEsIHRvID0gMC45LCBieSA9IDAuMDUpLCB2ZXJib3NlID0gVFJVRSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjRGVtdWx0aXBsZXhpbmcgcmVzdWx0cyB7LnRhYnNldH0KYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjI0NlbGxzIGNsYXNzaWZpY2F0aW9uCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkYXRhdGFibGUoYXMubWF0cml4KHRhYmxlKGhhc2h0YWcxQG1ldGEuZGF0YSRNVUxUSV9JRCkpLGNvbG5hbWVzID0gIk51bWJlciBvZiBjZWxscyIpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIFZpb2xpbnBsb3QgKGZlYXR1cmVzKQpgYGAKCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9ClZsblBsb3QoaGFzaHRhZzEsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSxwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIFZpb2xpbnBsb3QgKEhUTyBjb3VudHMpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KVmxuUGxvdChoYXNodGFnMSxmZWF0dXJlcyA9IGMoIm5Db3VudF9IVE8iKSxwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgdFNORXMgYmFzZWQgb24gSFRPCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KIyBDYWxjdWxhdGUgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgSFRPCmh0by5kaXN0Lm10eCA8LSBhcy5tYXRyaXgoZGlzdCh0KEdldEFzc2F5RGF0YShvYmplY3QgPSBoYXNodGFnMSwgYXNzYXkgPSAiSFRPIikpKSkKCiMgQ2FsY3VsYXRlIHRTTkUgZW1iZWRkaW5ncyB3aXRoIGEgZGlzdGFuY2UgbWF0cml4Cmhhc2h0YWcxIDwtIFJ1blRTTkUoaGFzaHRhZzEsIGRpc3RhbmNlLm1hdHJpeCA9IGh0by5kaXN0Lm10eCwgcGVycGxleGl0eSA9IDEwMCkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxlY2hvPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQpEaW1QbG90KGhhc2h0YWcxLCBncm91cC5ieSA9ICJNVUxUSV9JRCIscmVkdWN0aW9uID0gInRzbmUiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIEhUTyBtYXJnaW4KYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA3LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KVHNuZTwtZGF0YS5mcmFtZSgKICB0U05FXzEgPSBoYXNodGFnMUByZWR1Y3Rpb25zJHRzbmVAY2VsbC5lbWJlZGRpbmdzWywxXSwKICB0U05FXzI9IGhhc2h0YWcxQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDJdLAogIGdlbmU9IGhhc2h0YWcxQG1ldGEuZGF0YSRIVE9fbWFyZ2luCikKCkhUTz0gaGFzaHRhZzFAbWV0YS5kYXRhJE1VTFRJX0lECk1heD1tYXgoaGFzaHRhZzFAbWV0YS5kYXRhJEhUT19tYXJnaW4pCk1pbj1taW4oaGFzaHRhZzFAbWV0YS5kYXRhJEhUT19tYXJnaW4pCmdncGxvdChUc25lLGFlcyh4PXRTTkVfMSx5PXRTTkVfMikpK2dlb21fcG9pbnQoYWVzKGNvbG9yPWdlbmUsc2hhcGU9SFRPKSkrCiAgICAgICAgICAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsbWlkPSJvcmFuZ2UiLGhpZ2g9InJlZCIsbmFtZT0iSFRPIG1hcmdpbiIsbWlkcG9pbnQ9KE1heCtNaW4pLzIpK3NjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1KSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBSaWRnZSBwbG90cwoKKipWaXN1YWxpemUgZW5yaWNobWVudCBmb3Igc2VsZWN0ZWQgSFRPcyB3aXRoIHJpZGdlIHBsb3RzKioKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KUmlkZ2VQbG90KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbMToyXSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVszOjRdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMSwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzU6Nl0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNzo4XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMjIFNhbXBsZSBJbmZvcm1hdGlvbgoKVGhlIGFuYWx5c2lzIHdpbGwgYmUgcnVuIG9uIHRoZSBzYW1wbGUgMS4KCkR1cmluZyB0aGUgc2FtcGxlIGxvYWRpbmcsIHdlIGZpbHRlciBjZWxscyB0aGF0IGRvIG5vdCBwYXNzIHRoZSBmb2xsb3dpbmcgZmlsdGVycy4gICAKSGVyZSBhcmUgdGhlIGRlc2NyaXB0aW9uIG9mIHRob3NlIHBhcmFtZXRlcnMgaW4gdGhlIFNldXJhdCAqQ3JlYXRlU2V1cmF0T2JqZWN0KiBmdW5jdGlvbjoKICAKKiBtaW4uZ2VuZXM6IEluY2x1ZGUgY2VsbHMgd2hlcmUgYXQgbGVhc3QgMjAwIGdlbmVzIGFyZSBkZXRlY3RlZAoqIG1pbi5jZWxsczogSW5jbHVkZSBnZW5lcyB3aXRoIGRldGVjdGVkIGV4cHJlc3Npb24gaW4gYXQgbGVhc3QgMyBjZWxscwoKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQphIDwtIGxlbmd0aChjb2xuYW1lcyhoYXNodGFnMUBhc3NheXMkUk5BQGRhdGEpKQpwcmludChwYXN0ZSgiQWZ0ZXIgdGhvc2UgZmlsdGVycywgdGhlIHJlbWFpbmluZyBjZWxsIG51bWJlciBpcyIsIGEpLCBxdW90ZSA9IEZBTFNFKSAKYGBgCgoKCmBgYHtyIGRvdWJsZXRfbmVnYXRpdmVfcmVtb3ZhbCwgcmVzdWx0cz0nYXNpcycsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQojYWRkIEV4cDEgY2VsbCBpZGVudGl0eQpIVE9fY3IxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpCkhUT19jdDEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtY3RybCIgKSkKSFRPX21yMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKQpIVE9fbXQxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU0iICkpCkhUT19wcjEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tUCIgKSkKSFRPX3B0MSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKQpIVE9fcG1yMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgKSkKSFRPX3BtdDEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTVAiICkpCkhUT19kMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIkRvdWJsZXQiICkpCkhUT19uMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIk5lZ2F0aXZlIiApKQoKSFRPX3RoeW11czEgPSBjKEhUT19jdDEsSFRPX210MSxIVE9fcHQxLEhUT19wbXQxKQpIVE9fc3BsZWVuMSA9IGMoSFRPX2NyMSxIVE9fbXIxLEhUT19wcjEsSFRPX3BtcjEpCkhUT19pZGVudGlmaWVkMSA9IGMoSFRPX3RoeW11czEsIEhUT19zcGxlZW4xKQoKCiMgQ3JlYXRlIGEgU2V1cmF0IG9iamVjdCB3aXRob3V0IGRvdWJsZXQgYW5kIHVuYXNzaWduZWQgY2VsbHMgKHJlbW92ZSAibmVnYXRpdmUiLCAiZG91YmxldCIgJiAibm90aGluZyIpKQpjbGVhbi5zdWJzZXQxIDwtIHN1YnNldCh4ID0gaGFzaHRhZzEsIGNlbGxzID0gSFRPX2lkZW50aWZpZWQxKQpWbG5QbG90KGNsZWFuLnN1YnNldDEsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KYSA8LSBsZW5ndGgoY29sbmFtZXMoY2xlYW4uc3Vic2V0MUBhc3NheXMkUk5BQGRhdGEpKQpwcmludChwYXN0ZSgiQWZ0ZXIgcmVtb3ZpbmcgZG91YmxldHMgYW5kIG5lZ2F0aXZlIGNlbGxzLCB0aGUgcmVtYWluaW5nIGNlbGwgbnVtYmVyIGlzIiwgYSksIHF1b3RlID0gRkFMU0UpIApgYGAKCgpgYGB7ciBwcm9jZXNzaW5nXzEsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgT0JKRUNUIE9ORSBQUk9DRVNTSU5HIEFORCBTQVZFCiMxLSBRQyAKU2V1cmF0MSA8LSBRQ19mdW5jdGlvbl9taXRvX3RocmVzaG9sZChTZXVyYXQgPSBjbGVhbi5zdWJzZXQxLCBtaXRvX3RocmVzaG9sZCA9IDAuMSwgZG9fcGxvdCA9IEZBTFNFKQogIAojMi0gRmluZCB2YXJpYWJsZSBnZW5lcwpTZXVyYXQxIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IFNldXJhdDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiUk5BIiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCBkby5wbG90PVRSVUUpCgpTZXVyYXQxIDwtIFNjYWxlRGF0YShTZXVyYXQxLCAKICAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iUk5BIiwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICNkby5zY2FsZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIApTZXVyYXQxIDwtIFJ1blBDQShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlJOQSIsCiAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAjaWYgVFJVRSBwcmludCB0aGUgdG9wIGdlbmVzIGZvciBlYWNoIFBDCiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAgVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBTZXVyYXQxKSwgCiAgICAgICAgICAgICAgICAgICAgc2VlZC51c2UgPSAxMjM0LAogICAgICAgICAgICAgICAgICAgIG5wY3MgPSA1MCkgIyBzdXIgbGVzIDUwIHByZW1pZXJlcyBjb21wb3NhbnRlcwogIApFbGJvd1Bsb3QoU2V1cmF0MSwgbmRpbXMgPSA1MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdDEgPC0gUHJvamVjdERpbShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCiAgClNldXJhdDEgPC0gUnVuVFNORShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgICBkby5mYXN0ID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMTIzNCwKICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MjAsICMgVXNlcyAyMCBmaXJzdCBQQ3MKICAgICAgICAgICAgICAgICAgICAgcGVycGxleGl0eSA9IDQwKQogIApTZXVyYXQxIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gU2V1cmF0MSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjIwICwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlLnJlY2FsYyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWR1Y3Rpb24gPSAicGNhIikKClNldXJhdDEgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IFNldXJhdDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSBSRVNPTFVUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpClNldXJhdDEgPC0gUnVuVU1BUChvYmplY3QgPSBTZXVyYXQxLCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToyMCkKICAKc2F2ZShTZXVyYXQxLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIE1pdG9jaG9uZHJpYWwgcGVyY2VudGFnZSB2ZXJzdXMgbkZlYXR1cmVzCmBgYAoKYGBge3IgbWl0b192c19uZmVhdHVyZXMsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkZjwtZGF0YS5mcmFtZShtdWx0aS5pZD1TZXVyYXQxQG1pc2Mkb2xkX21ldGFfZGF0YSRNVUxUSV9JRCxwZXJjZW50Lm1pdG89U2V1cmF0MUBtaXNjJG9sZF9tZXRhX2RhdGEkcGVyY2VudC5taXRvLG5GZWF0dXJlX1JOQT1TZXVyYXQxQG1pc2Mkb2xkX21ldGFfZGF0YSRuRmVhdHVyZV9STkEpCmdncGxvdGx5KGdncGxvdChkZixhZXMoeD1uRmVhdHVyZV9STkEseT1wZXJjZW50Lm1pdG8sY29sb3I9bXVsdGkuaWQpKStnZW9tX3BvaW50KCkpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgVU1BUApgYGAKCmBgYHtyIFVNQVBfSFRPX3NldXJhdF8xLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQxLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIExvYWRpbmcgdGhlIHNlY29uZCBleHBlcmltZW50CmBgYAoKCmBgYHtyIHBhdGgyX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgTG9hZCBwYXRoIGZvciBmaWxlcwpQQVRIX01PVVNFX0RBVEEyIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDNfRGF0YS9SZXBsaWNhdGUyL21STkEiKSkKUFJPSkVDVF9OQU1FMiA8LSBwYXN0ZSgiMTBYXyIsIFNBTVBMRTIsIHNlcCA9ICIiKQpQQVRIX0hUT19EQVRBMiA8LSAocGFzdGUwKFdPUktJTkdfRElSLCIvMDJfU2V1cmF0X2FuYWx5c2lzLzAzX0RhdGEvUmVwbGljYXRlMi9IVE8iKSkKUEFUSF9BRFRfREFUQTIgPC0gKHBhc3RlMChXT1JLSU5HX0RJUiwiLzAyX1NldXJhdF9hbmFseXNpcy8wM19EYXRhL1JlcGxpY2F0ZTIvQURUIikpCmBgYAoKYGBge3IgU2FtcGxlX2xvYWRpbmdfMiwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBDcmVhdGUgU2V1cmF0IG9iamVjdCBhbmQgYXBwbHkgZmlsdGVyaW5nICAgCiMgUmVhZCAxMFggZGF0YQptb3VzZV9kYXRhMiA8LSBSZWFkMTBYKGRhdGEuZGlyID0gUEFUSF9NT1VTRV9EQVRBMikKCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20yIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTIiKQpgYGAKCmBgYHtyICwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBMb2FkIGluIHRoZSBVTUkgbWF0cml4CnVtaV9zcGFyc2UyIDwtIEdldEFzc2F5RGF0YShvYmplY3QgPSBOb3RfcHJvY2Vzc2VkX1NldXJhdF9tMiwgc2xvdCA9ICJjb3VudHMiKQoKIyBMb2FkIGluIHRoZSBIVE8gY291bnQgbWF0cml4CnJhdy5odG8yIDwtIFJlYWQxMFgoUEFUSF9IVE9fREFUQTIsIGdlbmUuY29sdW1uID0gMSkKaHRvMiA8LSByYXcuaHRvMltjKDE6OCksXQoKcm93bmFtZXMoaHRvMikgPC0gYygiU3BsZWVuLU1QIiwiU3BsZWVuLU0iLCJTcGxlZW4tY3RybCIsIlNwbGVlbi1QIiwiVGh5bXVzLU1QIiwiVGh5bXVzLU0iLCJUaHltdXMtY3RybCIsIlRoeW11cy1QIikKCiMgU2VsZWN0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEhUTwpqb2ludF9iY3MyIDwtIGludGVyc2VjdChjb2xuYW1lcyh1bWlfc3BhcnNlMiksY29sbmFtZXMoaHRvMikpCmh0bzIgPC0gYXMubWF0cml4KGh0bzJbLGpvaW50X2JjczJdKQoKIyBDb25maXJtIHRoYXQgdGhlIEhUTyBoYXZlIHRoZSBjb3JyZWN0IG5hbWVzCnByaW50IChyb3duYW1lcyhodG8yKSkKYGBgCgpgYGB7cixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CnBhcihtZnJvdz1jKDEsMSkpCnBhcihsYXM9MikKcGFyKG1hcj1jKDUsMTUsMywzKSkKYmFycGxvdChyb3dTdW1zKGh0bzIpLCBtYWluID0gInNlcXVlbmNlZCBIVE8gZGlzdHJpYnV0aW9uIiwgaG9yaXo9VFJVRSkKCnJvd1N1bXMoaHRvMikKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyMjIFNldHVwIHNldXJhdCBvYmplY3QgYW5kIGFkZCBpbiB0aGUgaHRvIGRhdGEKIyBTZXR1cCBTZXVyYXQgb2JqZWN0Cmhhc2h0YWcyIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSB1bWlfc3BhcnNlMlssam9pbnRfYmNzMiBdLCBhc3NheSA9ICJSTkEiLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTIiKQoKIyBOb3JtYWxpemUgUk5BIGRhdGEgd2l0aCBsb2cgbm9ybWFsaXphdGlvbgpoYXNodGFnMiA8LSBOb3JtYWxpemVEYXRhKGhhc2h0YWcyLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKIyBGaW5kIGFuZCBzY2FsZSB2YXJpYWJsZSBnZW5lcwpoYXNodGFnMiA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhoYXNodGFnMixkby5wbG90ID0gRixzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKaGFzaHRhZzIgPC0gU2NhbGVEYXRhKGhhc2h0YWcyLGdlbmVzLnVzZSA9IGhhc2h0YWcyQGFzc2F5cyRSTkFAdmFyLmZlYXR1cmVzLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyMjIEFkZGluZyBIVE8gZGF0YSBhcyBhbiBpbmRlcGVuZGVudCBhc3NheQojIEFkZCBIVE8gZGF0YSBhcyBhIG5ldyBhc3NheSBpbmRlcGVuZGVudCBmcm9tIFJOQQpoYXNodGFnMltbIkhUTyJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBodG8yKQpoYXNodGFnMiA8LSBTZXRBc3NheURhdGEoaGFzaHRhZzIsYXNzYXkgPSAiSFRPIixzbG90ID0gImNvdW50cyIsbmV3LmRhdGEgPSBodG8yKQojIE5vcm1hbGl6ZSBIVE8gZGF0YSwgaGVyZSB3ZSB1c2UgY2VudGVyZWQgbG9nLXJhdGlvIChDTFIpIHRyYW5zZm9ybWF0aW9uCmhhc2h0YWcyIDwtIE5vcm1hbGl6ZURhdGEoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiQ0xSIixkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiNSdW4gSFRPZGVtdXgganVzdCB0byBnZXQgdGhlIEhUT19tYXhJRCBmaWVsZApoYXNodGFnMiA8LSBIVE9EZW11eChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIiwgcG9zaXRpdmUucXVhbnRpbGUgPSAwLjk5LCB2ZXJib3NlID0gRkFMU0UpCiNEZW11bHRpcGxleCBjZWxscyBiYXNlZCBvbiBIVE8gZW5yaWNobWVudApoYXNodGFnMiA8LSBNVUxUSXNlcURlbXV4KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLGF1dG9UaHJlc2ggPSBUUlVFLCBtYXhpdGVyID0gMTAscXJhbmdlID0gc2VxKGZyb20gPSAwLjEsIHRvID0gMC45LCBieSA9IDAuMDUpLCB2ZXJib3NlID0gVFJVRSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjRGVtdWx0aXBsZXhpbmcgcmVzdWx0cyB7LnRhYnNldH0KYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjI0NlbGxzIGNsYXNzaWZpY2F0aW9uCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkYXRhdGFibGUoYXMubWF0cml4KHRhYmxlKGhhc2h0YWcyQG1ldGEuZGF0YSRNVUxUSV9JRCkpLGNvbG5hbWVzID0gIk51bWJlciBvZiBjZWxscyIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgVmlvbGlucGxvdCAoZmVhdHVyZXMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIikscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBWaW9saW4gcGxvdHMgKEhUTyBjb3VudHMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkNvdW50X0hUTyIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyB0U05FcyBiYXNlZCBvbiBIVE8KYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMgQ2FsY3VsYXRlIGEgZGlzdGFuY2UgbWF0cml4IHVzaW5nIEhUTwpodG8uZGlzdC5tdHggPC0gYXMubWF0cml4KGRpc3QodChHZXRBc3NheURhdGEob2JqZWN0ID0gaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIpKSkpCgojIENhbGN1bGF0ZSB0U05FIGVtYmVkZGluZ3Mgd2l0aCBhIGRpc3RhbmNlIG1hdHJpeApoYXNodGFnMiA8LSBSdW5UU05FKGhhc2h0YWcyLCBkaXN0YW5jZS5tYXRyaXggPSBodG8uZGlzdC5tdHgsIHBlcnBsZXhpdHkgPSAxMDApCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpEaW1QbG90KGhhc2h0YWcyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgSFRPIG1hcmdpbgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDcsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpUc25lPC1kYXRhLmZyYW1lKAogIHRTTkVfMSA9IGhhc2h0YWcyQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDFdLAogIHRTTkVfMj0gaGFzaHRhZzJAcmVkdWN0aW9ucyR0c25lQGNlbGwuZW1iZWRkaW5nc1ssMl0sCiAgZ2VuZT0gaGFzaHRhZzJAbWV0YS5kYXRhJEhUT19tYXJnaW4KKQoKSFRPPSBoYXNodGFnMkBtZXRhLmRhdGEkTVVMVElfSUQKTWF4PW1heChoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKTWluPW1pbihoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKCmdncGxvdChUc25lLGFlcyh4PXRTTkVfMSx5PXRTTkVfMikpK2dlb21fcG9pbnQoYWVzKGNvbG9yPWdlbmUsc2hhcGU9SFRPKSkrCiAgICAgICAgICAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsbWlkPSJvcmFuZ2UiLGhpZ2g9InJlZCIsbmFtZT0iSFRPIG1hcmdpbiIsbWlkcG9pbnQ9KE1heCtNaW4pLzIpK3NjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1KSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBSaWRnZSBwbG90cwoKKipWaXN1YWxpemUgZW5yaWNobWVudCBmb3Igc2VsZWN0ZWQgSFRPcyB3aXRoIHJpZGdlIHBsb3RzKioKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbMToyXSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVszOjRdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzU6Nl0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNzo4XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CgojIyBTYW1wbGUgSW5mb3JtYXRpb24KClRoZSBhbmFseXNpcyB3aWxsIGJlIHJ1biBvbiB0aGUgc2FtcGxlIDIuCgpEdXJpbmcgdGhlIHNhbXBsZSBsb2FkaW5nLCB3ZSBmaWx0ZXIgY2VsbHMgdGhhdCBkbyBub3QgcGFzcyB0aGUgZm9sbG93aW5nIGZpbHRlcnMuCgpVc2VkIHBhcmFtZXRlcnMgaW4gdGhlIFNldXJhdCAqQ3JlYXRlU2V1cmF0T2JqZWN0KiBmdW5jdGlvbjoKKiBtaW4uZ2VuZXM6IDMgLiBJbmNsdWRlIGNlbGxzIHdoZXJlIGF0IGxlYXN0IDMgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiAyMDAgLiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCAyMDAgY2VsbHMKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQphIDwtbGVuZ3RoKGNvbG5hbWVzKGhhc2h0YWcyQGFzc2F5cyRSTkFAZGF0YSkpCnByaW50KHBhc3RlKCJBZnRlciB0aG9zZSBmaWx0ZXJzLCB0aGUgcmVtYWluaW5nIGNlbGwgbnVtYmVyIGlzIiwgYSksIHF1b3RlID0gRkFMU0UpIApgYGAKCmBgYHtyIGNlbGxfc2VsZWN0XzIsIHJlc3VsdHM9J2FzaXMnLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KI2FkZCBFeHAyIGNlbGwgaWRlbnRpdHkKSFRPX2NyMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKQpIVE9fY3QyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtY3RybCIgKSkKSFRPX21yMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiU3BsZWVuLU0iICkpCkhUT19tdDIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1NIiApKQpIVE9fcHIyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tUCIgKSkKSFRPX3B0MiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLVAiICkpCkhUT19wbXIyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tTVAiICkpCkhUT19wbXQyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtTVAiICkpCkhUT19kMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiRG91YmxldCIgKSkKSFRPX24yIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJOZWdhdGl2ZSIgKSkKCkhUT190aHltdXMyID0gYyhIVE9fY3QyLEhUT19tdDIsSFRPX3B0MixIVE9fcG10MikKSFRPX3NwbGVlbjIgPSBjKEhUT19jcjIsSFRPX21yMixIVE9fcHIyLEhUT19wbXIyKQpIVE9faWRlbnRpZmllZDIgPSBjKEhUT190aHltdXMyLCBIVE9fc3BsZWVuMikKCiMgQ3JlYXRlIGEgU2V1cmF0IG9iamVjdCB3aXRob3V0IGRvdWJsZXQgYW5kIHVuYXNzaWduZWQgY2VsbHMgKHJlbW92ZSAibmVnYXRpdmUiLCAiZG91YmxldCIgJiAibm90aGluZyIpKQpjbGVhbi5zdWJzZXQyIDwtIHN1YnNldCh4ID0gaGFzaHRhZzIsIGNlbGxzID0gSFRPX2lkZW50aWZpZWQyKQpWbG5QbG90KGNsZWFuLnN1YnNldDIsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KYSA8LWxlbmd0aChjb2xuYW1lcyhjbGVhbi5zdWJzZXQyQGFzc2F5cyRSTkFAZGF0YSkpCnByaW50KHBhc3RlKCJBZnRlciByZW1vdmluZyBkb3VibGV0cyBhbmQgbmVnYXRpdmUgY2VsbHMsIHRoZSByZW1haW5pbmcgY2VsbCBudW1iZXIgaXMiLCBhKSwgcXVvdGUgPSBGQUxTRSkgCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBBZGRpbmcgQURUCmBgYAoKCmBgYHtyIGxvYWRfYWR0LCAgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMgTG9hZCBpbiB0aGUgVU1JIG1hdHJpeAp1bWkgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IGNsZWFuLnN1YnNldDIsIHNsb3QgPSAiY291bnRzIikKCiMgTG9hZCBpbiB0aGUgQURUIGNvdW50IG1hdHJpeApyYXcuYWR0IDwtIFJlYWQxMFgoUEFUSF9BRFRfREFUQTIsIGdlbmUuY29sdW1uID0gMSkKYWR0IDwtIHJhdy5hZHRbYygxOjYpLF0KCnJvd25hbWVzKGFkdCkgPC0gYygiQ0Q0IiwiQ0Q1IiwiQ0Q4IiwiQ0QyNSIsIkNENDQiLCJDRDY5IikKCiNjcmVhdGUgYW4gZW1wdHkgbWF0cml4IGNvbnRhaW5pbmcgTkFzCkNlbGwubGlzdCA8LSBjb2xuYW1lcyhHZXRBc3NheURhdGEob2JqZWN0ID0gY2xlYW4uc3Vic2V0MltbIlJOQSJdXSwgc2xvdCA9ICJkYXRhIiApICkKQURULmxpc3QgPC0gYyh1bmlxdWUocm93bmFtZXMoYWR0KSkpCm1hdC5hZHQgPC0gbWF0cml4KG5yb3cgPSBsZW5ndGgoQURULmxpc3QpLCBuY29sID0gbGVuZ3RoKENlbGwubGlzdCkpCnJvd25hbWVzKG1hdC5hZHQpID0gQURULmxpc3QKY29sbmFtZXMobWF0LmFkdCkgPSBDZWxsLmxpc3QKCiMgR2V0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEFEVApqb2ludF9iY3MgPC0gaW50ZXJzZWN0KGNvbG5hbWVzKHVtaSksY29sbmFtZXMoYWR0KSkKYWR0IDwtIGFzLm1hdHJpeChhZHRbLGpvaW50X2Jjc10pCgojIEZpbGwgdGhlIGVtcHR5IG1hdHJpeCB3aXRoIHZhbHVlcyB3aGVuIGV4aXN0aW5nCm1hdC5hZHRbLGpvaW50X2Jjc108LWFkdFssam9pbnRfYmNzXQoKIyBBZGQgQURUIGRhdGEgYXMgYSBuZXcgYXNzYXkgaW5kZXBlbmRlbnQgZnJvbSBSTkEKY2xlYW4uc3Vic2V0MltbIkFEVCJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBtYXQuYWR0Wyxjb2xuYW1lcyhjbGVhbi5zdWJzZXQyKV0pCgojIE5vcm1hbGl6ZSBBRFQgZGF0YSwgaGVyZSB3ZSB1c2UgY2VudGVyZWQgbG9nLXJhdGlvIChDTFIpIHRyYW5zZm9ybWF0aW9uCmNsZWFuLnN1YnNldDIgPC0gTm9ybWFsaXplRGF0YShjbGVhbi5zdWJzZXQyLCBhc3NheSA9ICJBRFQiLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJDTFIiKQoKI1NjYWxlCmNsZWFuLnN1YnNldDIgPC0gU2NhbGVEYXRhKGNsZWFuLnN1YnNldDIsIGFzc2F5ID0gIkFEVCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQpBRFQgbGlzdCA6CmBgYAoKCmBgYHtyICwgcmVzdWx0cz0nYXNpcycsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpwcmludCAocm93bmFtZXMoYWR0KSkKYGBgCgpgYGB7ciBTaWduaWZpY2FudF9QQywgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBPQkpFQ1QgVFdPIFBST0NFU1NJTkcgQU5EIFNBVkUKIzEtIFFDIApTZXVyYXQyIDwtIFFDX2Z1bmN0aW9uX21pdG9fdGhyZXNob2xkKFNldXJhdCA9IGNsZWFuLnN1YnNldDIsIG1pdG9fdGhyZXNob2xkID0gMC4xLCBkb19wbG90ID0gRkFMU0UpCiAgCiMyLSBGaW5kIHZhcmlhYmxlIGdlbmVzClNldXJhdDIgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCB2ZXJib3NlID0gRkFMU0UsIGRvLnBsb3Q9VFJVRSkKICAKU2V1cmF0MiA8LSBTY2FsZURhdGEoU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgYXNzYXk9IlJOQSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgZG8uY2VudGVyID0gVFJVRSkKICAKU2V1cmF0MiA8LSBSdW5QQ0Eob2JqZWN0ID0gU2V1cmF0MiwKICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgI2lmIFRSVUUgcHJpbnQgdGhlIHRvcCBnZW5lcyBmb3IgZWFjaCBQQwogICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gIFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiksIAogICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMTIzNCwKICAgICAgICAgICAgICAgICAgICBucGNzID0gNTApIAogIApFbGJvd1Bsb3QoU2V1cmF0MiwgbmRpbXMgPSA0MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdDIsCiAgICAgICAgICAgICAgICAgICAgICAgbmZlYXR1cmVzLnByaW50ID0gMjAsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCgpTZXVyYXQyIDwtIFJ1blRTTkUob2JqZWN0ID0gU2V1cmF0MiwKICAgICAgICAgICAgICAgICAgICAgZG8uZmFzdCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICBzZWVkLnVzZSA9IDEyMzQsCiAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjIwLCAKICAgICAgICAgICAgICAgICAgICAgcGVycGxleGl0eSA9IDQwKQogIApTZXVyYXQyIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdDIgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IFNldXJhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSBSRVNPTFVUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgClNldXJhdDIgPC0gUnVuVU1BUChvYmplY3QgPSBTZXVyYXQyLCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToyMCkKICAKc2F2ZShTZXVyYXQyLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTIsICIuUm9iaiIpKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTWl0b2Nob25kcmlhbCBwZXJjZW50YWdlIHZlcnN1cyBuRmVhdHVyZXMKYGBgCgpgYGB7ciBtaXRvX3ZzX25mZWF0dXJlczIsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkZjwtZGF0YS5mcmFtZShtdWx0aS5pZD1TZXVyYXQyQG1pc2Mkb2xkX21ldGFfZGF0YSRNVUxUSV9JRCxwZXJjZW50Lm1pdG89U2V1cmF0MkBtaXNjJG9sZF9tZXRhX2RhdGEkcGVyY2VudC5taXRvLG5GZWF0dXJlX1JOQT1TZXVyYXQyQG1pc2Mkb2xkX21ldGFfZGF0YSRuRmVhdHVyZV9STkEpCmdncGxvdGx5KGdncGxvdChkZixhZXMoeD1uRmVhdHVyZV9STkEseT1wZXJjZW50Lm1pdG8sY29sb3I9bXVsdGkuaWQpKStnZW9tX3BvaW50KCkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBVTUFQOgpgYGAKCmBgYHtyIFVNQVBfSFRPX3NldXJhdF8yLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQyLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KI01lcmdpbmcgb3VyIHR3byBleHBlcmltZW50cwpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTG9hZCBzZXBhcmF0ZSBSIG9iamVjdApZb3UgY2FuIGxvYWQgb2JqZWN0cyBkb25lIHdpdGggdGhlIGNvZGUgYWJvdmUuCk9yIG91ciBvYmplY3QgPz8gKGxpbmsgKQpgYGAKCmBgYHtyIFNhbXBsZXNfbG9hZGluZyxldmFsPShwYXJ0MiA9PSBUUlVFICkgLGluY2x1ZGU9RkFMU0V9CiNsb2FkIGFsbCBzZXVyYXQgb2JqZWN0cyBidWlsdCBwcmV2aW91c2x5CmxvYWQocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQpsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdF9jbGVhbi1zdWJzZXRfdG9tZXJnZV8iLCBTQU1QTEUyLCAiLlJvYmoiKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIEludGVncmF0aW5nIHRoZSAyIHNldXJhdCBvYmplY3RzIHdpdGggc2V1cmF0IGludGVncmF0aW9uIChjY2EpCmBgYAoKYGBge3IsIENDQSwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGluY2x1ZGU9RkFMU0V9CiMgR2VuZSBzZWxlY3Rpb24gZm9yIGlucHV0IHRvIENDQQpGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBTZXVyYXQxLCAKICAgICAgICBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIHZlcmJvc2UgPSBGQUxTRSkKRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCB2ZXJib3NlID0gRkFMU0UpCgpleHAuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0ID0gYyhTZXVyYXQyLFNldXJhdDEpLCBkaW1zID0gMTozMCkKCmdlbmUxIDwtIHJvd25hbWVzKEdldEFzc2F5RGF0YShTZXVyYXQxLCBhc3NheSA9ICJSTkEiLCBzbG90ID0gImRhdGEiICkpCmdlbmUyIDwtIHJvd25hbWVzKEdldEFzc2F5RGF0YShTZXVyYXQyLCBhc3NheSA9ICJSTkEiLCBzbG90ID0gImRhdGEiICkpCmNvbW1vbl9nZW5lcyA8LSBSZWR1Y2UoaW50ZXJzZWN0LCBsaXN0KGdlbmUxLGdlbmUyKSkKCmV4cDEuMi5pbnRlZ3JhdGVkIDwtIEludGVncmF0ZURhdGEoYW5jaG9yc2V0ID0gZXhwLmFuY2hvcnMsIGZlYXR1cmVzLnRvLmludGVncmF0ZSA9IGNvbW1vbl9nZW5lcyxkaW1zID0gMTozMCkKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CmEgPC0gbGVuZ3RoKGdlbmUxKQpiIDwtIGxlbmd0aChnZW5lMikKYyA8LSBsZW5ndGgoY29tbW9uX2dlbmVzKQoKcHJpbnQocGFzdGUoIldlIGlkZW50aWZpZWQgIixhLCIgZXhwcmVzc2VkIGluIHNhbXBsZTEgYW5kICIsYiwiIGV4cHJlc3NlZCBpbiBzYW1wbGUyLiIsYywiYXJlIGluIGNvbW1vbiBpbiB0aGlzIHR3byBzZXQgYW5kIHdpbGwgdGhlIGludGVncmF0ZWQgaW4gdGhlIG1lcmdlZCBhbmQgY29ycmVjdGVkIG9iamVjdC4iKSwgcXVvdGUgPSBGQUxTRSkgCgpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFVNQVA6CgojIEFuYWx5c2lzIHBhcnQKCiMjIFNhbXBsZSBJbmZvcm1hdGlvbgoKVGhlIGFuYWx5c2lzIHdpbGwgYmUgcnVuIG9uIHRoZSByZXBsaWNhdGUgMSBhbmQgMi4KCkR1cmluZyB0aGUgc2FtcGxlIGxvYWRpbmcsIHdlIGZpbHRlciBjZWxscyB0aGF0IGRvIG5vdCBwYXNzIHRoZSBmb2xsb3dpbmcgZmlsdGVycy4gV2UgYWxzbyBmaWx0ZXIgY2VsbHMgdGhhdCBhcmUgZGV0ZWN0ZWQgYXMgaHVtYW4vbW91c2UgbXVsdGlwbGV0IHVzaW5nIHRoZWlyIGJhcmNvZGVzLiAgCkhlcmUgYXJlIHRoZSBkZXNjcmlwdGlvbiBvZiB0aG9zZSBwYXJhbWV0ZXJzIGluIHRoZSBTZXVyYXQgKkNyZWF0ZVNldXJhdE9iamVjdCogZnVuY3Rpb246CgoqIG1pbi5nZW5lczogSW5jbHVkZSBjZWxscyB3aGVyZSBhdCBsZWFzdCB0aGlzIG1hbnkgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCB0aGlzIG1hbnkgY2VsbHMKCmBgYAoKYGBge3IgZmlsdGVycywgZXZhbD0ocGFydDIgPT0gVFJVRSApLHJlc3VsdHM9J2FzaXMnLGluY2x1ZGU9RkFMU0V9CiMgQWZmaWNoZSBsZXMgcGFyYW1ldHJlcwpGaWx0ZXJfcGFyYW1ldGVycyA8LSBkYXRhLmZyYW1lKCkKRmlsdGVyX3BhcmFtZXRlcnNbIlZhbHVlIiwgIm1pbi5jZWxscyJdIDwtIDMKRmlsdGVyX3BhcmFtZXRlcnNbIlZhbHVlIiwgIm1pbi5nZW5lcyJdIDwtIDIwMAprYWJsZShGaWx0ZXJfcGFyYW1ldGVycywgImh0bWwiLCBhbGlnbiA9ICJjIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQphIDwtIGxlbmd0aChjb2xuYW1lcyhleHAxLjIuaW50ZWdyYXRlZCkpCgpwcmludChwYXN0ZSgiQWZ0ZXIgdGhvc2UgZmlsdGVycywgYW5kIG1lcmdpbmcgTVlDX1BURU5fMDEgYW5kIE1ZQ19QVEVOMDIgdGhlIHJlbWFpbmluZyBjZWxsIG51bWJlciBpcyIsYSksIHF1b3RlID0gRkFMU0UpIAoKYGBgCgoKYGBge3IgY2VsbF9zZWxlY3QsZXZhbD0ocGFydDIgPT0gVFJVRSApLCByZXN1bHRzPSdhc2lzJyxpbmNsdWRlPUZBTFNFfQojIyMgYWRkIEV4cDEgY2VsbCBpZGVudGl0eQojYWRkIEV4cDEgY2VsbCBpZGVudGl0eQpIVE9fY3I2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fY3Q2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1jdHJsIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXI2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcHI2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1QIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcHQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG1yNiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tTVAiICkpLCJfMiIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19wbXQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NUCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKCiMjIyBhZGQgRXhwMiBjZWxsIGlkZW50aXR5CkhUT19jcjIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19jdDIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtY3RybCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX21yMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1NIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXQyIDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLU0iICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19wcjIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tUCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3B0MiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1QIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG1yMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1NUCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3BtdDIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtTVAiICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCgoKCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YSRIVE8gPSAibm90aGluZyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19jcjIsXSRIVE8gPSAiV1Qgc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX2N0MixdJEhUTyA9ICJXVCB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fY3I2LF0kSFRPID0gIldUIHNwbGVlbiIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19jdDYsXSRIVE8gPSAiV1QgdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3ByMixdJEhUTyA9ICJQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcHQyLF0kSFRPID0gIlBURU4tIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wcjYsXSRIVE8gPSAiUFRFTi0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3B0NixdJEhUTyA9ICJQVEVOLSB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fbXIyLF0kSFRPID0gIk1ZQy0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX210MixdJEhUTyA9ICJNWUMtIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19tcjYsXSRIVE8gPSAiTVlDLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fbXQ2LF0kSFRPID0gIk1ZQy0gdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3BtcjIsXSRIVE8gPSAiTXljLSBQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcG10MixdJEhUTyA9ICJNeWMtIFBURU4tIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wbXI2LF0kSFRPID0gIk15Yy0gUFRFTi0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3BtdDYsXSRIVE8gPSAiTXljLSBQVEVOLSB0aHltdXMiCgpIVE9fdGh5bXVzID0gYyhIVE9fY3QyLEhUT19tdDIsSFRPX3B0MixIVE9fcG10MixIVE9fY3Q2LEhUT19tdDYsSFRPX3B0NixIVE9fcG10NikKSFRPX3NwbGVlbiA9IGMoSFRPX2NyMixIVE9fbXIyLEhUT19wcjIsSFRPX3BtcjIsSFRPX2NyNixIVE9fbXI2LEhUT19wcjYsSFRPX3BtcjYpCgppZGVudGlmaWVkIDwtIGMoSFRPX3RoeW11cyxIVE9fc3BsZWVuKQpWbG5QbG90KGV4cDEuMi5pbnRlZ3JhdGVkLGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKVmxuUGxvdChleHAxLjIuaW50ZWdyYXRlZCxmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJIVE8iKQpWbG5QbG90KGV4cDEuMi5pbnRlZ3JhdGVkLGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKQoKU2V1cmF0IDwtIGV4cDEuMi5pbnRlZ3JhdGVkCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBVTUFQIGFuZCBjbHVzdGVyaW5nIHBhcmFtZXRlcgpgYGAKCmBgYHtyIFNpZ25pZmljYW50X1BDX21lcmdlLCBldmFsPShwYXJ0MiA9PSBUUlVFICksaW5jbHVkZT1GQUxTRX0KIyBUcmFpdGVtZW50IGRlIGwnb2JqZXQKU2V1cmF0IDwtIFNjYWxlRGF0YSggb2JqZWN0ID0gIFNldXJhdCwgCiAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iaW50ZWdyYXRlZCIsCiAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRvLmNlbnRlciA9IFRSVUUpCiAgClNldXJhdCA8LSBSdW5QQ0Eob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoU2V1cmF0KSwgbnBjcyA9IDUwLCBzZWVkLnVzZSA9IDEyMzQsIHZlcmJvc2UgPSBGQUxTRSkKICAKRWxib3dQbG90KFNldXJhdCwgbmRpbXMgPSA0MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdCwKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTIpCiAgClNldXJhdCA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFNldXJhdCwgCiAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjEyICwgCiAgICAgICAgICAgICAgICAgIGFzc2F5PSJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKSMsIAogICAgICAgICAgICAgICAgICAjZm9yY2UucmVjYWxjID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICNyZWR1Y3Rpb24gPSAicGNhIikKICAKU2V1cmF0IDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSBTZXVyYXQsIAogICAgICAgICAgICAgICAgICByZXNvbHV0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIHJhbmRvbS5zZWVkID0gMTIzNCkKICAgIAogICNUbyBtYWtlIHRoZSBVTUFQCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToxMikKICAKRGltUGxvdChvYmplY3QgPSBTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCiAgCnNhdmUoU2V1cmF0LCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0LWludGVncmF0ZWRfcmVwMV9yZXAyLlJvYmoiKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBNZXJnZSBjaGVja2luZyB7LnRhYnNldH0KIyMjIEhUTwpgYGAKCmBgYHtyLGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1GQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiSFRPIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkrCiAgICAgICAgICAgZ2d0aXRsZSgiVU1BUCBjb2xvcnJlZCBieSBIVE8gY2xhc3NpZmljYXRpb24iKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBPcmlnLmlkZW50cwpgYGAKCmBgYHtyLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDEpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFQtY2VsbCBzZWxlY3Rpb24gey50YWJzZXR9CkFjY29yZGluZyB0byBULWNlbGwgbWFya2VycyB3ZSB3aWxsIGV4Y2x1ZGUgQ2QzZCBsb3cgY2x1c3RlcnM6IDEzIChCY2VsbHMpLCAxMSwgMTQsIDE3IChtb25vY3l0ZXMvbWFjcm9waGFnZXMpLgpBY2NvcmRpbmcgdG8gVC1jZWxsIG1hcmtlcnMgd2Ugd2lsbCBleGNsdWRlIENkM2QvQ2QzZSBsb3cgY2x1c3RlcnM6IDExIChCY2VsbHMpLCAxMywgMTcsIDE4LCAxOSAobW9ub2N5dGVzL21hY3JvcGhhZ2VzKSwgMTYsIDE0IChJTEMvTkspLgoKIyMjIEtub3duIFJOQSBCIGFuZCBUIG1hcmtlcnMKYGBgCgpgYGB7ciBidF9tYXJrZXJzX2NoZWNraW5nLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89RkFMU0V9CkRpbVBsb3QoU2V1cmF0LCBsYWJlbCA9IFQpCmJjZWxsX2tub3duX21hcmtlcnMgPC0gYygiQ2Q3NCIsIk1zNGExIiwiQ2QxOSIsIkNkM2QiKQpGZWF0dXJlUGxvdChvYmplY3QgPSBTZXVyYXQsIGZlYXR1cmVzID0gYmNlbGxfa25vd25fbWFya2VycywgcmVkdWN0aW9uID0gInVtYXAiLCAgY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpiY2VsbF9rbm93bl9tYXJrZXJzIDwtIGMoIkNkMTQiLCJGY2dyMyIsIlRyZGMiLCJDZDNkIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGJjZWxsX2tub3duX21hcmtlcnMsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGMoIklsMnJhIiwiS2xyZzEiLCJJbDdyIiwiUm9yYSIpLCByZWR1Y3Rpb24gPSAidW1hcCIsIG9yZGVyID0gVFJVRSwgY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpGZWF0dXJlUGxvdChvYmplY3QgPSBTZXVyYXQsIGZlYXR1cmVzID0gYygiRW9tZXMiLCJOY3IxIiwiVGJ4MjEiLCJLaXQiKSwgcmVkdWN0aW9uID0gInVtYXAiLCBvcmRlciA9IFRSVUUsIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKI05yYzEgPSBOSwojSUw3UiB0byBzZXBhcmF0ZSBJTEMgZnJvbSBOSzsgSUw3UisgRU9NRVMrIHNob3VsZCBiZSBJTEMxOyBFT01FUysgSUw3Ui0gc2hvdWxkIGJlIE5LCmBgYAoKYGBge3IgVGNlbGxfc2VsZWN0aW9uLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KI3JlbW92ZSBjbHVzdGVyIDExLDEyLDEzLDE3ICgjQmNlbGxzICYgbWFjcm9waGFnZXMpClQuU2V1cmF0IDwtIHN1YnNldCh4ID0gU2V1cmF0LCBpZGVudHMgPSBjKCIxMSIsIjEzIiwiMTQiLCIxNiIsIjE3IiwiMTgiLCIxOSIpLCBpbnZlcnQgPSBUUlVFKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgcmUgY2x1c3RlcmluZwpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFLCBldmFsPShwYXJ0MiA9PSBUUlVFICl9CiMgSU5URUdSQVRFIE9CSkVDVCBBTkQgU0FWRQoKIyBTZWxlY3Rpb24gd2FzIGFscmVhZHkgZG9uZSBhdCB0aGUgaW50ZWdyYXRpb24gc3RlcCwgZXZlbiBhZnRlciByZXN1YnNldHRpbmcgaXQgaXMgd29ydGggdG8gcmVzZWxlY3QgKGh0dHBzOi8vZ2l0aHViLmNvbS9zYXRpamFsYWIvc2V1cmF0L2lzc3Vlcy8xNTI4KS4gUk5BIHNob3VsZCBiZSB1c2VkLCBidXQgdGhlbiBiYXRjaCBpcyBiYWNrLCBzdWJzZXR0aW5nIGJlZm9yZSBpbnRlZ3JhdGlvbiBpcyBub3QgZ29vZCBuZWl0aGVyIChiZXR0ZXIgdG8ga2VlcCBjZWxscyB0aGF0IGNhbiBiZSBhbGlnbmVkKS4uLiAKICAKVC5TZXVyYXQgPC0gU2NhbGVEYXRhKCBvYmplY3QgPSAgVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgI2RvLnNjYWxlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIApULlNldXJhdCA8LSBSdW5QQ0Eob2JqZWN0ID0gVC5TZXVyYXQsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhULlNldXJhdCksIG5wY3MgPSAxMDAsIHNlZWQudXNlID0gMTIzNCwgdmVyYm9zZSA9IEZBTFNFKQogIApFbGJvd1Bsb3QoVC5TZXVyYXQsIG5kaW1zID0gNTAsIHJlZHVjdGlvbiA9ICJwY2EiKQoKVC5TZXVyYXQgPC0gUHJvamVjdERpbShvYmplY3QgPSBULlNldXJhdCwKICAgICAgICAgICAgICAgICAgbmZlYXR1cmVzLnByaW50ID0gMjAsCiAgICAgICAgICAgICAgICAgIGRpbXMucHJpbnQgPSAxOjEwKQogIApULlNldXJhdCA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFQuU2V1cmF0LAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MTggLCAKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKSMsIAogICAgICAgICAgICAgICAgICAjZm9yY2UucmVjYWxjID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICNyZWR1Y3Rpb24gPSAicGNhIikKICAKICBULlNldXJhdCA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IDEuOCwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgI1RvIG1ha2UgdGhlIFVNQVAKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwogIFQuU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJwY2EiLCBzZWVkLnVzZSA9IDEyMzQsIGRpbXMgPSAxOjE4KQogIAogIERpbVBsb3Qob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCiAgcDEgPC0gRGltUGxvdChvYmplY3QgPSBULlNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKICBwMiA8LSBEaW1QbG90KG9iamVjdCA9IFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIAogICAgICBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSkgKyBOb0xlZ2VuZCgpCiAgCiAgZ3JpZC5hcnJhbmdlKHAxLHAyLG5yb3cgPSAxLCBuY29sID0yLCBuZXdwYWdlPVRSVUUpCgogIHNhdmUoVC5TZXVyYXQsIGZpbGUgPSBwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC1tZXJnZWRfY2xlYW4tc3Vic2V0IiwgIi5Sb2JqIikpCmBgYAoKYGBge3IgLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KIyMjIGFkZCBFeHAyIGNlbGwgaWRlbnRpdHkgCnNwbGVlbi5jZWxscyA8LSBjKHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU0iICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1QIiApKSkKCnRoeW11cy5jZWxscyA8LSBjKHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLWN0cmwiICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU0iICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU1QIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKSkKClQuU2V1cmF0QG1ldGEuZGF0YSR0aXNzdWUgPSAibm90aGluZyIKVC5TZXVyYXRAbWV0YS5kYXRhW3NwbGVlbi5jZWxscyxdJHRpc3N1ZSA9ICJTcGxlZW4iClQuU2V1cmF0QG1ldGEuZGF0YVt0aHltdXMuY2VsbHMsXSR0aXNzdWUgPSAiVGh5bXVzIgoKRGltUGxvdChULlNldXJhdCkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBULWNlbGwgdW1hcHMgey50YWJzZXR9CiMjIyBIVE8KYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CmdncGxvdGx5KERpbVBsb3QoVC5TZXVyYXQsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIGNsdXN0ZXJpbmcKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CihEaW1QbG90KFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBsYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAxKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIEVORCBPRiBQUkVQUk9DRVNTSU5HCldlIG9idGFpbiB0aGUgZmluYWwgb2JqZWN0IHdpdGggY2x1c3RlcmluZyB0byBzdGFydCB0aGUgYW5hbHlzaXMKYGBgCgo8ZGV0YWlscz4KICA8c3VtbWFyeT4qKlNlc3Npb24gSW5mbyoqPC9zdW1tYXJ5PgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKPC9kZXRhaWxzPgo=